using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace OpenComposite.Base.Designer
{
	public class ComboBox : DesignerControl
	{
		#region Initialization
		public ComboBox()
		{
			init();
		}
		private void init()
		{
			this.BeginUpdate();

			_comboBox = new System.Windows.Forms.ComboBox();
			_comboBox.Visible = false;
			_comboBox.Cursor = Cursors.Default;
			_comboBox.KeyDown += new System.Windows.Forms.KeyEventHandler(_comboBox_KeyDown);

			this.Cursor = System.Windows.Forms.Cursors.IBeam;

			//this.Name = "comboBox" + GetCount(typeof(ComboBox));
			this.Text = this.Name;

			this.BackColor = Color.Transparent;

			_penBorder = new Pen(Color.Gray);
			_penBorder.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;

			_format = new StringFormat();
			_format.Trimming = StringTrimming.EllipsisCharacter;

			this.EndUpdate();
		}
		#endregion

		#region Public Members

		#region Properties

		public BorderVisibilityStyle BorderVisibilityStyle
		{
			get { return _borderVisibilityStyle; }
			set
			{
				if ( _borderVisibilityStyle != value ) {
					_borderVisibilityStyle = value;
					Repaint();
				}
			}
		}

		public bool AutoSize
		{
			get { return _bAutoSize; }
			set { _bAutoSize = value; }
		}
		public System.Windows.Forms.ComboBox.ObjectCollection Items
		{
			get { return _comboBox.Items; }
		}
		public int ItemHeight
		{
			get { return _comboBox.ItemHeight; }
			set { _comboBox.ItemHeight = value; }
		}
		public int DropDownHeight
		{
			get { return _comboBox.DropDownHeight; }
			set { _comboBox.DropDownHeight = value; }
		}
		public System.Windows.Forms.ComboBoxStyle DropDownStyle
		{
			get { return _comboBox.DropDownStyle; }
			set { _comboBox.DropDownStyle = value; }
		}
		public int DropDownWidth
		{
			get { return _comboBox.DropDownWidth; }
			set { _comboBox.DropDownWidth = value; }
		}
		public System.Windows.Forms.ComboBox SystemComboBox
		{
			get { return _comboBox; }
		}

		#endregion

		#region Events
		#endregion

		#region Methods
		#endregion

		#region Overrides

		public override bool CanFocused
		{
			get
			{
				return true;
			}
		}
		public override bool CanSelect
		{
			get
			{
				return false;
			}
		}

		public override void Dispose()
		{
			dispose(_penBorder);
			dispose(_comboBox);
			dispose(_format);

			base.Dispose();
		}
		public override void Paint(System.Windows.Forms.PaintEventArgs pe)
		{
			Rectangle bounds = GetPaintBounds();
			pe.Graphics.FillRectangle(this.BackBrush, bounds);

			if ( BorderVisibilityStyle == BorderVisibilityStyle.Always ||
				 ( Status.MouseOverCtrl == this && ( BorderVisibilityStyle == BorderVisibilityStyle.MouseOver || BorderVisibilityStyle == BorderVisibilityStyle.MouseOverAndFocus ) ) ||
				 ( Status.FocusedContol == this && ( BorderVisibilityStyle == BorderVisibilityStyle.Focus || BorderVisibilityStyle == BorderVisibilityStyle.MouseOverAndFocus ) )
			) {
				SmoothingMode sm = pe.Graphics.SmoothingMode;
				pe.Graphics.SmoothingMode = SmoothingMode.None;
				pe.Graphics.DrawRectangle(_penBorder, bounds);
				pe.Graphics.SmoothingMode = sm;
			}
			pe.Graphics.DrawString(this.Text, this.Font, this.ForeBrush, bounds, _format);
		}

		public override string ToString()
		{
			return this.Text;
		}

		#endregion

		#endregion

		#region Protected Members

		#region Overrides

		protected override void OnTextChanged(EventArgs e)
		{
			this.BeginUpdate();
			if ( this.AutoSize && this.DesignerViewControl != null ) {
				using ( Graphics g = this.DesignerViewControl.CreateGraphics() ) {
					SizeF s = g.MeasureString(this.Text, this.Font);
					if ( this.Width != (int)s.Width ) this.Height = (int)Math.Ceiling(s.Width);
					if ( this.Height != (int)s.Height ) this.Height = (int)Math.Ceiling(s.Height);
				}
			}
			this.EndUpdate();
			base.OnTextChanged(e);
		}
		protected override void OnDesignerViewChanged(EventArgs e)
		{
			base.OnDesignerViewChanged(e);
			//if ( this.DesignerViewControl == null )
			//    _comboBox.Parent = null;
			//else
			//    this.DesignerViewControl.ViewControls.Add(_comboBox);
		}
		protected override void OnMouseClick(System.Windows.Forms.MouseEventArgs e)
		{
			base.OnMouseClick(e);
			showComboBox();
		}

		#endregion

		#endregion

		#region Private Members

		#region Variables

		private bool _bAutoSize;
		private Pen _penBorder;
		private StringFormat _format;
		private System.Windows.Forms.ComboBox _comboBox;
		private BorderVisibilityStyle _borderVisibilityStyle;

		#endregion

		#region Methods

		private void showComboBox()
		{
			Rectangle bounds = this.Bounds;
			if ( this.Parent != null )
				bounds = this.Parent.RectangleToDesignerView(bounds);

			if ( !this.DesignerViewControl.ViewControls.Contains(_comboBox) )
				this.DesignerViewControl.ViewControls.Add(_comboBox);

			if ( this.DesignerViewControl != null )
				this.DesignerViewControl.MouseDown += new MouseEventHandler(DesignerViewControl_MouseDown);

			_comboBox.Location = bounds.Location;
			_comboBox.Width = bounds.Width + 20;
			_comboBox.Text = this.Text;
			_comboBox.Visible = true;
			_comboBox.Focus();
			_comboBox.SelectAll();
		}
		private void hideComboBox(bool bCancel)
		{
			_comboBox.Hide();
			if ( this.DesignerViewControl != null ) {
				if ( this.DesignerViewControl.ViewControls.Contains(_comboBox) )
					this.DesignerViewControl.ViewControls.Remove(_comboBox);
				this.DesignerViewControl.MainPanel.Focus();
			}

			if ( !bCancel )
				this.Text = _comboBox.Text;
			if ( this.DesignerViewControl != null ) {
				this.DesignerViewControl.MouseDown -= new MouseEventHandler(DesignerViewControl_MouseDown);
			}

		}

		#endregion

		#region Event Handlers

		private void _comboBox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			if ( e.KeyCode == System.Windows.Forms.Keys.Escape )
				hideComboBox(true);
			else if ( e.KeyCode == System.Windows.Forms.Keys.Enter || e.KeyCode == System.Windows.Forms.Keys.Return )
				hideComboBox(false);
		}

		private void DesignerViewControl_MouseDown(object sender, MouseEventArgs e)
		{
			hideComboBox(false);
		}

		#endregion

		#endregion
	}
}
